require "open-uri"
require 'stringio'
require 'iconv'


class SiteHeartBeat < ActiveRecord::Base

  def before_save
    raise '不支持'
  end

  def pre_one
    SiteHeartBeat.first(:conditions => [ 'id < ? and site_heart_beat_daily_stat_id =? ', id , site_heart_beat_daily_stat_id ], :order => 'id desc' )
  end

  def user
    site_heart_beat_daily_stat.site_health_setting.user
  end

  def site_health_setting
    site_heart_beat_daily_stat.site_health_setting
  end
  
  # 把脉
  def self.take_pulse!(setting)
    record_health_result! take_pulse(setting)
  end
  
  def self.record_health_result!(health_result)
    health_result[:result] == :good ? (
      SiteHeartBeat::Available.create! health_result[:attributes]
    ) : (
      SiteHeartBeat::Unavailable.create! health_result[:attributes]
    )
  end
  
  def self.take_pulse(setting)
    logger.debug "taking #{setting.name} pulse ..."
    attributes = {
      :site_heart_beat_daily_stat => SiteHeartBeatDailyStat.find_or_create_by_site_health_setting_id_and_created_on(
        setting.id,
        Date.today
      ) ,
      :started_at => Time.now
    }
    def attributes.good_health!
      self[:ended_at] = Time.now
      {
        :result => :good,
        :attributes => self
      }
    end
    def attributes.bad_health!
      self[:ended_at] = Time.now
      {
        :result => :bad,
        :attributes => self
      }
    end
    # 把脉
    begin
      take_pulse_by_url_and_content!(
        setting.site_url,
        setting.content_keyword
      ) ? (
        logger.debug "take #{setting.name} pulse success"  
        attributes.good_health!
      ) : (
        logger.error "take #{setting.name} pulse failed"
        attributes.bad_health!
      )
    rescue
      logger.error "take #{setting.name} pulse failed :#{$!}"      
      attributes.bad_health!
    end    
  end
  
  def self.take_pulse_by_url_and_content!(url,content)
    match?(open(url),content)
  end
  
  private
  def self.match?(html_page,content) 
    lines = html_page.each_with_object([]) do |line, lines|   
      lines << line.to_s
    end    
    case
    when gb2312?(lines)
      logger.debug "--------------gb2312"
      lines.each do |line|
        #logger.debug "====match:#{content}====#{line.match(content)}======"
        #logger.debug gbk_to_utf8(line)
        #logger.debug "=============="
        return true if gb2312_to_utf8(line).match(content)
      end
      return false
    when gbk?(lines)
      logger.debug "--------------gbk"
      lines.each do |line|
        #logger.debug "====match:#{content}====#{line.match(content)}======"
        #logger.debug gbk_to_utf8(line)
        #logger.debug "=============="
        return true if gbk_to_utf8(line).match(content)
      end
      return false
    else
      logger.debug "--------------utf8"
      lines.each do |line|
        #logger.debug "====match:#{content}====#{line.match(content)}======"
        #logger.debug line
        #logger.debug "=============="
        return true if line.match(content)
      end
      return false
    end
    
  end
  
  def self.gb2312?(lines)
    lines.each do |line|
      #logger.debug line + '------gb2312'
      return true if line.match('gb2312') or line.match('GB2312')
    end
    return false
  end
  
  def self.gbk?(lines)
    lines.each do |line|
      #logger.debug line + '------gbk'
      return true if line.match('gbk') or line.match('GBK')
    end
    return false
  end
  
  def self.gbk_to_utf8(gbk_string)
    Iconv.iconv("UTF-8//IGNORE","GBK//IGNORE",gbk_string).to_s
  end
  
  def self.gb2312_to_utf8(gbk_string)
    Iconv.iconv("UTF-8//IGNORE","GB2312//IGNORE",gbk_string).to_s
  end

  def send_sm
    begin
      send_sm!
    rescue Exception => error
      puts error
      logger.error error
    end
  end

  def send_email
    begin
      send_email!
    rescue Exception => error
      puts error
      logger.error error
    end
  end
end
